
package compiler;

import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;

import org.antlr.runtime.ANTLRFileStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.antlr.stringtemplate.StringTemplateGroup;


import parser.TBTLexer;
import parser.TBTParser;
import typechecker.TypeCheckerMain;

/**
 * The compiler front-end:
 * 1.  Parses the input file (currently ./test/prelude.tbt)
 * 1'. Typechecks the program (not yet implemented)
 * 2.  Based on templates from ./templates it emits Java code 
 *     in the ./compiler_out/TermClosure.java file.
 * 3.  It uses the runtime library from ./src/compiler_rt
 */
public class CompilerMain {

	public static void compile(String filename){
		PrintStream fos = null;
		FileReader fr = null;
	    TBTLexer lex = null;
        CommonTree t = null;
        StringTemplateGroup templates = null;

        if( !TypeCheckerMain.typecheck(filename)){
        	return;
        }
        
        // Open all IO streams
        try {
    		lex = new TBTLexer(new ANTLRFileStream(filename, "UTF8"));
			fos = new PrintStream("D:\\workspace\\TBT-front-end\\compiler_out\\output\\TermClosure.java");
			fr = new FileReader("D:\\workspace\\TBT-front-end\\templates\\compiler.stg");
			templates = new StringTemplateGroup(fr);
			fr.close();
		} catch (IOException e1) {
			System.out.println("IO error : " + e1.getMessage());
		}

		// Split the file into lexical atoms
        CommonTokenStream cts = new CommonTokenStream(lex);
        TBTParser g = new TBTParser(cts);
		try {
			// Parse and obatin the Abstract Syntax Tree
			t = (CommonTree) g.program().getTree();
		} catch (RecognitionException e1) {
			System.out.println("SYNTAX ERROR: " + e1.getMessage());
		}
    
        CommonTreeNodeStream cnts = new CommonTreeNodeStream(t);
        TBTJcompiler cpl= new TBTJcompiler(cnts);
        TBTJcompiler.prog_return ret = null;
        cpl.setTemplateLib(templates);        
        // Compile the program to JAVA
        try {
        	ret = cpl.prog();
		} catch (RecognitionException e1) {
			System.out.println("SYNTAX ERROR (AST): " + e1.getMessage());
		}
		
		// Print the program to the output stream
		fos.println(ret.getTemplate().toString());		
	}
	
	public static void main(String args[]){
		// monadic.tbt , negative.tbt, parser.tbt, dict.tbt
		compile("D:\\workspace\\TBT-front-end\\test\\debug.tbt");		
//		compile("D:\\workspace\\TBT-front-end\\test\\prelude.tbt");		
	}
}
